"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lane.chang on '07/09/2022'
    comment: 自定义输入文本框(Label + LineEdit)
"""
import sys
from PyQt5.QtWidgets import (QLineEdit, QLabel, QWidget, QHBoxLayout, QApplication, QPushButton, QVBoxLayout,
                             QSpacerItem, QSizePolicy)
from PyQt5.QtCore import QTimer

from project.component import TITLE_FONT, CONTENT_FONT


class UserText(QWidget):
    """ 文本框组件
    """
    def __init__(self,
                 label_text: str = '',
                 default_text: str = '',
                 text_align: int | None = None,
                 width: int | None = None,
                 object_name: str = '',
                 gap=0,
                 explain_text='',
                 parent=None):
        """
        :param label_text:
        :param default_text:
        :param text_align: 文本对齐方式
        :param width: 文本框宽度
        :param object_name: 设置对象名称
        :param gap: label和textbox之间的间距
        :param explain_text: 说明文本
        :param parent:
        """
        super().__init__(parent)

        # 创建子控件
        self.label = QLabel(label_text, self)
        self.label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)  # 不可被拉伸
        self.label.setFont(TITLE_FONT)
        self.text_box = QLineEdit(default_text, self)
        self.text_box.setFont(CONTENT_FONT)
        if text_align is not None:
            self.text_box.setAlignment(text_align)
        if object_name:
            self.text_box.setObjectName(object_name)
        if width is not None:
            self.text_box.setFixedWidth(width)

        # 中间弹簧
        self.gap_spacer = QSpacerItem(gap, 0, QSizePolicy.Fixed, QSizePolicy.Minimum)

        # 2.布局
        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)  # 去掉外边距，可自由调整
        layout.addWidget(self.label)
        layout.addItem(self.gap_spacer)
        layout.addWidget(self.text_box)

        if explain_text:
            self.explain_text = explain_text
            self.explain = QLabel(explain_text, self)
            self.explain.setFont(CONTENT_FONT)
            self.explain.setStyleSheet("color: red;")
            layout.addWidget(self.explain)
            self.flush_explain_text()

        # 3. 自动全选
        self.text_box.mousePressEvent = self._select_all_on_click

    def text(self):
        """
        :return:
        """
        return self.text_box.text()

    def set_text(self, txt):
        """
        :param txt:
        :return:
        """
        self.text_box.setText(txt)

    def object_name(self):
        """
        :return:
        """
        return self.text_box.objectName()

    def set_title(self, txt):
        """
        :param txt:
        :return:
        """
        self.label.setText(txt)

    def flush_explain_text(self):
        """ 刷新说明文本
        :return:
        """
        self.explain.setText(self.explain_text.replace('#{text}', self.text()))

    def _select_all_on_click(self, event):
        """
        :param event:
        :return:
        """
        # -------- 内部辅助 --------
        QTimer.singleShot(0, self.text_box.selectAll)
        # 继续交给原来的事件处理，保证光标等逻辑正常
        QLineEdit.mousePressEvent(self.text_box, event)


# ----------------- Demo 窗口 -----------------
class DemoWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('LabeledLineEdit Demo')

        # 创建两个自定义组件
        self.name_edit = UserText('姓名:', '张三', explain_text='这是在测试#{text}的名称')
        self.age_edit = UserText('年龄:', '18')

        # 一个按钮，打印当前内容
        self.print_btn = QPushButton('打印当前文本')
        self.print_btn.clicked.connect(self.print_texts)

        # 整体布局
        main_layout = QVBoxLayout(self)
        main_layout.addWidget(self.name_edit)
        main_layout.addWidget(self.age_edit)
        main_layout.addWidget(self.print_btn)

    def print_texts(self):
        """
        :return:
        """
        print('姓名:', self.name_edit.text())
        print('年龄:', self.age_edit.text())


# ----------------- main -----------------
if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = DemoWindow()
    w.show()
    sys.exit(app.exec_())
